package com.fjec.user.shiro;

import com.fjec.common.enums.EnumLoginType;
import com.fjec.common.enums.EnumSysCode;
import com.fjec.common.exception.BizException;
import com.fjec.common.exception.LoginException;
import com.fjec.common.shiro.AccountInfo;
import com.fjec.common.shiro.MyUserToken;
import com.fjec.user.entity.SysUser;
import com.fjec.user.service.IUserService;
import com.google.common.base.Strings;
import org.apache.commons.collections.MapUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class WechatAppRealm extends AuthorizingRealm {

    private IUserService userService;

    public WechatAppRealm(IUserService userService) {
        this.userService = userService;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        String openId = (String) principal.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        List<String> roles = userService.getRoleCodesByOpenId(openId);
        simpleAuthorizationInfo.setRoles(new HashSet<>(roles));
        Set<String> permissions = new HashSet<>();
        for (String role : roles) {
            permissions.addAll(userService.getPermsByRoleCode(role));
        }
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        MyUserToken loginToken = (MyUserToken) token;
        String openId = loginToken.getUsername();
        String pwd = new String(loginToken.getPassword());
        if (Strings.isNullOrEmpty(openId)) {
            throw new LoginException(EnumSysCode.ERR_0030);
        }
        SysUser user = userService.getSysUserByOpenId(openId);
        if (user == null) {
            throw new LoginException(EnumSysCode.ERR_3004);
        }
        // 用户是否已被锁定
        if (user.getLocked() == 1) {
            throw new LoginException(EnumSysCode.ERR_3005);
        }
        List<String> roles = userService.getRoleCodesByOpenId(openId);
        // add by sz 2020-09-15 增加登录到小程序的商户类型 start
        // 普通用户
        Integer busiType = 1;
        if (roles != null && !roles.isEmpty()) {
            if (roles.contains("Purchasing")) {
                // 采购商
                busiType = 6;
            } else if (roles.contains("PkgPlant")) {
                // 包装厂
                busiType = 5;
            } else if (roles.contains("Material")) {
                // 农资厂
                busiType = 4;
            } else if (roles.contains("SortingPlant")) {
                // 分拣厂
                busiType = 3;
            } else if (roles.contains("Farmer")) {
                // 果农
                busiType = 2;
            }
        }

        // add by sz 2020-09-15 增加登录到小程序的商户类型 end
        Map<String, Object> m = userService.getSessionInfo(user.getId(), busiType);
        if (m != null) {
            Long busiId = MapUtils.getLong(m, "BusiId", 0L);
            String shopName = MapUtils.getString(m, "ShopName", "");
            String wxNickName = MapUtils.getString(m, "WxNickName", "水果平台用户");
            String headPic = MapUtils.getString(m, "HeadPic");
            AccountInfo.init(user.getId(), openId, roles, busiId, busiType, shopName, wxNickName, headPic);
        } else {
            throw new BizException(EnumSysCode.ERR_3002.getCode(), EnumSysCode.ERR_3002.getMsg());
        }
        // 记录登录日志
        userService.saveLoginLog(user.getId(), 2);
        return new SimpleAuthenticationInfo(openId, pwd, getName());
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        MyUserToken loginToken = (MyUserToken) token;
        if (loginToken.getLoginType() == EnumLoginType.WECHAT_APP) {
            return true;
        } else {
            return false;
        }
    }
}
